/**
 * 消息类型定义文件
 * 用于统一前端与Godot之间的消息数据结构
 * 支持WebSocket通信的标准化消息格式
 */

// 消息基本结构
// {
//   id: "唯一消息ID",
//   type: "消息类型",
//   data: { 消息数据 },
//   timestamp: 时间戳
// }

// 预定义的消息类型常量
export const MessageTypes = {
  // 系统消息类型
  CONNECT: 'system:connect',                    // 连接建立
  DISCONNECT: 'system:disconnect',              // 连接断开
  HEARTBEAT: 'system:heartbeat',                // 心跳
  ERROR: 'system:error',                        // 错误消息
  
  // 客户端注册相关
  REGISTER_CLIENT: 'system:register_client',    // 注册客户端
  CLIENT_REGISTERED: 'system:client_registered', // 客户端注册成功
  
  // 一对一连接标识消息类型
  REGISTER_PAIRING_ID: 'register_pairing_id',  // 注册配对标识
  PAIRING_SUCCESS: 'pairing_success',          // 配对成功
  PAIRING_ERROR: 'pairing_error',              // 配对错误
  
  // 原有业务消息类型
  JUMP: "jump",

  // 故障选择
  TROUBLE_SELECTED: "trouble_selected",

  // 控制面板
  CONTROL_PANEL_OPENED: "control_panel_opened",

  // 状态更新
  STATUS_UPDATE: "status_update",

  // 场景加载
  SCENE_LOADED: "scene_loaded",

  // 参数更新
  UPDATE_PARAMETERS: "update_parameters",

  // 控制命令
  CONTROL_COMMAND: "control_command",

  // 场景切换
  SWITCH_SCENE: "switch_scene",

  // 模拟重置
  RESET_SIMULATION: "reset_simulation",

  // 通用消息
  GENERAL_MESSAGE: "general_message",
};

/**
 * 创建标准化消息
 * @param {string} type - 消息类型
 * @param {object} data - 消息数据
 * @param {string} [id] - 可选的消息ID
 * @returns {object} 格式化后的消息对象
 */
export function createMessage(type, data = {}, id = null) {
  return {
    id: id || generateMessageId(),
    type,
    data,
    timestamp: Date.now()
  };
}

/**
 * 创建错误消息
 * @param {string} errorCode - 错误代码
 * @param {string} errorMessage - 错误消息
 * @param {object} [additionalInfo] - 附加信息
 * @returns {object} 错误消息对象
 */
export function createErrorMessage(errorCode, errorMessage, additionalInfo = {}) {
  return createMessage(MessageTypes.ERROR, {
    errorCode,
    errorMessage,
    ...additionalInfo
  });
}

/**
 * 验证消息格式是否正确
 * @param {Object} message - 要验证的消息对象
 * @returns {boolean} 是否为有效的消息格式
 */
export function validateMessage(message) {
  if (!message || typeof message !== 'object') {
    return false;
  }
  
  // 必需字段验证
  if (!message.type || typeof message.type !== 'string' || message.type.trim() === '') {
    return false;
  }
  
  // 兼容旧版本消息格式（如果没有id和timestamp）
  if (!message.id && !message.timestamp) {
    return true;
  }
  
  // 完整格式验证（WebSocket消息）
  if (message.id && message.timestamp) {
    return typeof message.timestamp === 'number' && 
           typeof message.data === 'object';
  }
  
  return true;
}

/**
 * 生成唯一消息ID
 * @returns {string} 唯一ID
 */
function generateMessageId() {
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 9);
}

/**
 * 构建WebSocket连接URL
 * @param {string} host - 主机地址
 * @param {number} port - 端口号
 * @param {boolean} useSSL - 是否使用SSL
 * @returns {string} 完整的WebSocket URL
 */
export function buildWebSocketUrl(host = 'localhost', port = 8080, useSSL = false) {
  const protocol = useSSL ? 'wss://' : 'ws://';
  return `${protocol}${host}:${port}`;
}

/**
 * 检查消息是否为系统消息
 * @param {string} messageType - 消息类型
 * @returns {boolean} 是否为系统消息
 */
export function isSystemMessage(messageType) {
  return messageType && messageType.startsWith('system:');
}

/**
 * 错误代码常量
 */
export const ErrorCodes = {
  // 连接相关错误
  CONNECTION_FAILED: 'CONN_FAIL',
  TIMEOUT: 'TIMEOUT',
  RECONNECT_FAILED: 'RECONNECT_FAIL',
  
  // 消息相关错误
  INVALID_MESSAGE_FORMAT: 'INVALID_FORMAT',
  UNKNOWN_MESSAGE_TYPE: 'UNKNOWN_TYPE',
  
  // 业务相关错误
  OPERATION_FAILED: 'OP_FAIL',
  PERMISSION_DENIED: 'PERM_DENIED',
  RESOURCE_NOT_FOUND: 'NOT_FOUND'
};

/**
 * 获取消息类型
 * @param {Object} message - 消息对象
 * @returns {string|null} 消息类型或null（如果格式无效）
 */
export function getMessageType(message) {
  if (validateMessage(message)) {
    return message.type;
  }
  return null;
}

/**
 * 获取消息数据
 * @param {Object} message - 消息对象
 * @returns {Object|null} 消息数据或null（如果格式无效）
 */
export function getMessageData(message) {
  if (validateMessage(message)) {
    return message.data;
  }
  return null;
}

export default {
  MessageTypes,
  ErrorCodes,
  createMessage,
  createErrorMessage,
  validateMessage,
  getMessageType,
  getMessageData,
  buildWebSocketUrl,
  isSystemMessage
};
